#ifndef H_KOGI_LIST_H
#define H_KOGI_LIST_H

#include "alloc.h"
#include "item.h"

#include <stdbool.h>
#include <stddef.h>

// Types
struct kogi_list_node {
    struct kogi_list_node* next;
    struct kogi_list_node* prev;
    struct kogi_item item;
};

struct kogi_list {
    struct kogi_list_node head;
    struct kogi_list_node tail;
    size_t size;
    kogi_alloc_fp alloc_fp;
    kogi_dealloc_fp dealloc_fp;
    void* alloc_context;
};

// Create/Destroy
int kogi_list_create(struct kogi_list*);
int kogi_list_destroy(struct kogi_list*);
void kogi_list_set_alloc(void*, kogi_alloc_fp, kogi_dealloc_fp);

// Size
static inline bool kogi_list_empty(struct kogi_list const*);
static inline size_t kogi_list_size(struct kogi_list const*);

// Access
static inline struct kogi_item kogi_list_back(struct kogi_list const*);
static inline struct kogi_item kogi_list_front(struct kogi_list const*);

// Add
int kogi_list_push_back(struct kogi_list*, struct kogi_item);
int kogi_list_push_front(struct kogi_list*, struct kogi_item);

#include "internal/list.inl"

#endif

